#include "VSPostEffectFunction.h"
#include "VSPostEffectSet.h"
#include "VSGraphicInclude.h"
#include "VSStream.h"
using namespace VSEngine2;
IMPLEMENT_RTTI_NoCreateFun(VSPostEffectFunction,VSObject)
IMPLEMENT_INITIAL_NO_CLASS_FACTORY_BEGIN(VSPostEffectFunction)
IMPLEMENT_INITIAL_NO_CLASS_FACTORY_END
BEGIN_ADD_PROPERTY(VSPostEffectFunction,VSObject)
REGISTER_PROPERTY(m_ShowName,ShowName,VSProperty::F_SAVE_LOAD_CLONE)
REGISTER_PROPERTY(m_bEnable,Enable,VSProperty::F_SAVE_LOAD_CLONE);
REGISTER_PROPERTY(m_pOwner,Owner,VSProperty::F_SAVE_LOAD_CLONE);
REGISTER_PROPERTY(m_pInput,Input,VSProperty::F_SAVE_LOAD_CLONE);
REGISTER_PROPERTY(m_pOutput,Output,VSProperty::F_SAVE_LOAD_CLONE);
END_ADD_PROPERTY
VSPostEffectFunction::VSPostEffectFunction()
{
	m_pInput.Clear();
	m_pOutput.Clear();
	m_bIsVisited = 0;
	m_pOwner = NULL;
	m_bEnable = true;
}
VSPostEffectFunction::VSPostEffectFunction(const VSUsedName & ShowName,VSPostEffectSet * pPostEffectSet)
{
	m_ShowName = ShowName;
	m_pInput.Clear();
	m_pOutput.Clear();
	VSMAC_ASSERT(pPostEffectSet);
	m_pOwner = pPostEffectSet;
	m_pOwner->AddPostEffectFunction(this);
	m_bEnable = true;
}
VSPostEffectFunction::~VSPostEffectFunction()
{
	for(unsigned int i = 0 ; i < m_pInput.GetNum() ; i++)
	{
		VSMAC_DELETE(m_pInput[i]);
	}
	for(unsigned int i = 0 ; i < m_pOutput.GetNum() ; i++)
	{
		VSMAC_DELETE(m_pOutput[i]);
	}
	m_pOwner->DeletePostEffectFunction(this);
	m_pPostEffectRender = NULL;
}
unsigned int VSPostEffectFunction::DiskUse()const
{
	unsigned int Use = VSObject::DiskUse();
	Use += m_ShowName.DiskUse();
	Use += sizeof(VSPostEffectSet *);
	Use += sizeof(unsigned int) * 2;
	Use += sizeof(VSInputNode *) * m_pInput.GetNum();
	Use += sizeof(VSOutputNode *) * m_pOutput.GetNum();
	Use += sizeof(bool);
	return Use;

}
bool VSPostEffectFunction::Save(VSStream & rStream,unsigned int &iSaveUse)const
{
	if(!VSObject::Save(rStream,iSaveUse))
		return false;

	if(!rStream.Write(&m_bEnable,sizeof(bool)))
		return 0;
	iSaveUse += sizeof(bool);

	m_ShowName.Save(rStream,iSaveUse);

	// 	if(!rStream.Write(&m_pOwner,sizeof(VSPostEffectSet *)))
	// 		return 0;
	if(!rStream.WriteObjectPtr(m_pOwner))
		return 0;
	iSaveUse += sizeof(VSPostEffectSet *);

	unsigned int uiInputNum = m_pInput.GetNum();
	if(!rStream.Write(&uiInputNum,sizeof(unsigned int)))
		return 0;
	iSaveUse += sizeof(unsigned int);

	unsigned int uiOutputNum = m_pOutput.GetNum();
	if(!rStream.Write(&uiOutputNum,sizeof(unsigned int)))
		return 0;
	iSaveUse += sizeof(unsigned int);

	for(unsigned int i = 0 ; i < uiInputNum ; i++)
	{
		// 		VSInputNode * pInputNode = m_pInput[i];
		// 		if(!rStream.Write(&pInputNode,sizeof(VSInputNode *)))
		// 			return 0;
		if(!rStream.WriteObjectPtr(m_pInput[i]))
			return 0;
		iSaveUse += sizeof(VSInputNode *);
	}

	for(unsigned int i = 0 ; i < uiOutputNum ; i++)
	{
		// 		VSOutputNode * pOutputNode = m_pOutput[i];
		// 		if(!rStream.Write(&pOutputNode,sizeof(VSOutputNode *)))
		// 			return 0;
		if(!rStream.WriteObjectPtr(m_pOutput[i]))
			return 0;
		iSaveUse += sizeof(VSOutputNode *);
	}
	return 1;
}
bool VSPostEffectFunction::Load(VSStream & rStream,unsigned int &iSaveUse)
{

	if(!VSObject::Load(rStream,iSaveUse))
		return false;

	if(!rStream.Read(&m_bEnable,sizeof(bool)))
		return 0;
	iSaveUse += sizeof(bool);

	m_ShowName.Load(rStream,iSaveUse);

	// 	VSPostEffectSet * pOwner = NULL;
	// 	if(!rStream.Read(&pOwner,sizeof(VSPostEffectSet *)))
	// 		return 0;
	// 	AddLink(pOwner);
	if(!rStream.ReadObjectPtr(m_pOwner))
		return 0;
	iSaveUse += sizeof(VSPostEffectSet *);

	unsigned int uiInputNum;
	if(!rStream.Read(&uiInputNum,sizeof(unsigned int)))
		return 0;
	iSaveUse += sizeof(unsigned int);

	unsigned int uiOutputNum;
	if(!rStream.Read(&uiOutputNum,sizeof(unsigned int)))
		return 0;
	iSaveUse += sizeof(unsigned int);

	m_pInput.SetBufferNum(uiInputNum);
	for(unsigned int i = 0 ; i < uiInputNum ; i++)
	{
		// 		VSInputNode * pPutNode = NULL;
		// 		if(!rStream.Read(&pPutNode,sizeof(VSInputNode *)))
		// 			return 0;
		// 		AddLink(pPutNode);
		if(!rStream.ReadObjectPtr(m_pInput[i]))
			return 0;
		iSaveUse += sizeof(VSInputNode *);
	}

	m_pOutput.SetBufferNum(uiOutputNum);
	for(unsigned int i = 0 ; i < uiOutputNum ; i++)
	{
		// 		VSOutputNode * pPutNode = NULL;
		// 		if(!rStream.Read(&pPutNode,sizeof(VSOutputNode *)))
		// 			return 0;
		// 		AddLink(pPutNode);
		if(!rStream.ReadObjectPtr(m_pOutput[i]))
			return 0;
		iSaveUse += sizeof(VSOutputNode *);
	}
	return 1;
}
bool VSPostEffectFunction::Clone(const VSObject *pObject,unsigned int uiType)
{
	//NO USE
	const VSPostEffectFunction* Temp = DynamicCast<VSPostEffectFunction>(pObject); 
	if(!Temp)
		return 0;
	if(VSObject::Clone(pObject,uiType))
	{
		m_bEnable	= Temp->m_bEnable;
		m_ShowName = Temp->m_ShowName;
		m_pInput.Clear();
		m_pInput.SetBufferNum(Temp->m_pInput.GetNum());
		for (unsigned int i = 0 ; i < m_pInput.GetNum() ; i++)
		{
			VSInputNode * pTemp1  = Temp->m_pInput[i];
			VSInputNode * pTemp2 =(VSInputNode *)VSObject::GetInstance((pTemp1)->GetType().GetName());
			pTemp2->Clone(pTemp1,uiType);
			m_pInput[i] = pTemp2;	
			((VSPutNode *)pTemp2)->SetOwner(this);
		}

		m_pOutput.Clear();
		m_pOutput.SetBufferNum(Temp->m_pOutput.GetNum());
		for (unsigned int i = 0 ; i < m_pOutput.GetNum() ; i++)
		{
			VSOutputNode * pTemp1  = Temp->m_pOutput[i];
			VSOutputNode * pTemp2 =(VSOutputNode *)VSObject::GetInstance((pTemp1)->GetType().GetName());
			pTemp2->Clone(pTemp1,uiType);
			m_pOutput[i] = pTemp2;	
			((VSPutNode *)pTemp2)->SetOwner(this);
		}
		m_pOwner = Temp->m_pOwner;
		return 1;
	}
	else
	{
		return 0;

	}
}
void VSPostEffectFunction::AddAllPutNodeTo(VSArray<VSPutNode *>& LinkArray)
{
	for (unsigned int i = 0 ; i < m_pInput.GetNum() ; i++)
	{

		LinkArray.AddElement(m_pInput[i]);	
	}

	for (unsigned int i = 0 ; i < m_pOutput.GetNum() ; i++)
	{

		LinkArray.AddElement(m_pOutput[i]);	
	}	
}
bool VSPostEffectFunction::Link(const VSArray<VSPutNode *>& OldLink,const VSArray<VSPutNode *>& NewLink)
{
	for (unsigned int i = 0 ; i < m_pInput.GetNum() ; i++)
	{

		if(!m_pInput[i]->Link(OldLink,NewLink))
			return 0;
	}

	for (unsigned int i = 0 ; i < m_pOutput.GetNum() ; i++)
	{

		if(!m_pOutput[i]->Link(OldLink,NewLink))
			return 0;
	}	
	return 1;
}
bool VSPostEffectFunction::Register(VSStream & rStream)const
{
	if (rStream.IsObjectRegister(this))
	{
		return 1;
	}
	if(!VSObject::Register(rStream))
		return 0;

	if(!m_pOwner->Register(rStream))
		return 0;
	for(unsigned int i = 0 ; i < m_pInput.GetNum() ; i++)
	{
		if(!m_pInput[i]->Register(rStream))
			return 0;
	}

	for(unsigned int i = 0 ; i < m_pOutput.GetNum() ;i++)
	{
		if(!m_pOutput[i]->Register(rStream))
			return 0;
	}
	return 1;

}
bool VSPostEffectFunction::Link(VSStream & rStream)
{
	if(!VSObject::Link(rStream))
		return 0;

	//m_pOwner = (VSPostEffectSet *)rStream.GetMapValue(GetNextLink());
	rStream.LinkObjectPtr(m_pOwner);
	for(unsigned int i = 0 ; i < m_pInput.GetNum() ; i++)
	{
		//m_pInput[i] = (VSInputNode *)rStream.GetMapValue(GetNextLink());
		rStream.LinkObjectPtr(m_pInput[i]);
	}

	for(unsigned int i = 0 ; i < m_pOutput.GetNum() ;i++)
	{
		//m_pOutput[i] = (VSOutputNode *)rStream.GetMapValue(GetNextLink());
		rStream.LinkObjectPtr(m_pOutput[i]);
	}

	return 1;
}
VSInputNode * VSPostEffectFunction::GetInputNode(unsigned int uiNodeID)const
{
	if(uiNodeID >=m_pInput.GetNum())
		return NULL;
	return m_pInput[uiNodeID];
}
VSInputNode * VSPostEffectFunction::GetInputNode(const VSString & NodeName)const
{
	for (unsigned int i  =0 ; i < m_pInput.GetNum(); i++)
	{
		if(m_pInput[i]->GetNodeName() == NodeName)
			return m_pInput[i];
	}
	return NULL;
}

VSOutputNode * VSPostEffectFunction::GetOutputNode(unsigned int uiNodeID)const
{
	if(uiNodeID >=m_pOutput.GetNum())
		return NULL;
	return m_pOutput[uiNodeID];
}
VSOutputNode * VSPostEffectFunction::GetOutputNode(const VSString & NodeName)const
{
	for (unsigned int i  =0 ; i < m_pInput.GetNum(); i++)
	{
		if(m_pOutput[i]->GetNodeName() == NodeName)
			return m_pOutput[i];
	}
	return NULL;
}
bool VSPostEffectFunction::ClearFlag()
{
	if(m_bIsVisited == 0)
		return 1;
	else
	{
		m_bIsVisited = 0;
		for(unsigned int i = 0 ; i < m_pInput.GetNum(); i++)
		{
			if(m_pInput[i]->GetOutputLink() == NULL)
				continue;
			else
			{
				((VSPostEffectFunction *)m_pInput[i]->GetOutputLink()->GetOwner())->ClearFlag();

			}

		}
		return 1;
	}
}